#include <string.h>
#include <iostream>
#include <poll.h>
#include <unistd.h>
#include "server.h"
// poll最大的文件描述符个数
//  #define MAX 10000
const int MAX = 10000;
int       main()
{
    // maxfs最大文件描述符+1
    int       listenfd, acceptfd, ret, maxfs, temfs, i, j;
    TcpServer server;
    listenfd = server.TcpInit();

    //用于存储文件描述符和其它相关事件(读，写或错误)的结构体
    struct pollfd fds[MAX];
    //文件描述符
    fds[0].fd = listenfd;
    //表示感兴趣的事件，这里设置为读事件
    fds[0].events = POLLIN;
    //表示实际发生的事件
    fds[0].revents = 0;
    maxfs          = 1;
    temfs          = maxfs;
    for(int i = 1; i < MAX; ++i) {
        //-1表示该位置没有可用的文件描述符
        fds[i].fd     = -1;
        fds[i].events = 0;
    }
    while(1) {
        ret = poll(fds, maxfs, 0);
        /**
         * @description:poll函数，用于实现io多路复用，与select类似，但是没有文件描述符限制
         * @param
         * {*}参数1:用于存放文件描述符和相关事件的结构体数组;参数2:fds数组个;参数3:超时检测
         * @return
         * {*}0:超时;-1:出错了;其它:准备好的文件描述符(即有事件发生的文件描述符)
         */
        if(-1 == ret) {
            perror("poll:");
            exit(-1);
        }
        //由于没有设置超时检测，不会出现返回值为0的情况
        for(i = 0; i < maxfs; ++i) {
            //产生读事件
            if(fds[i].revents & POLLIN) {
                if(fds[i].fd == listenfd) {
                    acceptfd = server.TcpAceept(listenfd);
                    for(j = 1; j < MAX; ++j) {
                        if(-1 == fds[j].fd) {
                            fds[j].fd      = acceptfd;
                            fds[j].events  = POLLIN;
                            fds[j].revents = 0;
                            // printf("j = %d maxfs =%d\n", j, maxfs);
                            printf("客户端%d连接\n", j);
                            // if (j == MAX)
                            // {
                            //     printf("close\n");
                            //     close(acceptfd);
                            // }
                            if(j >= maxfs) { maxfs = maxfs + 1; }
                            break;
                        }
                    }
                    //达到了最大容量
                } else {
                    char buf[64] = {0};
                    memset(buf, 0, sizeof(buf));
                    int len = read(fds[i].fd, buf, sizeof(buf));
                    if(0 >= len) {
                        close(fds[i].fd);
                        printf("客户端%d退出\n", i);
                        //类似于select的FD_CLR
                        fds[i].fd = -1;
                    }
                    printf("read:%dbytes,buf:%s\n", len, buf);
                }
            }
        }
    }
}